package com.daxia.ogmall.service;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.daxia.ogmall.basemodel.CoreUser;
import com.daxia.ogmall.common.CartStatus;
import com.daxia.ogmall.common.ProductSellingStatus;
import com.daxia.ogmall.dao.CartDAO;
import com.daxia.ogmall.dto.CartDTO;
import com.daxia.ogmall.dto.ProductDTO;
import com.daxia.ogmall.dto.SpecificationDTO;
import com.daxia.ogmall.dto.UserDTO;
import com.daxia.ogmall.model.Cart;
import com.daxia.ogmall.support.Page;
import com.daxia.ogmall.util.BeanMapper;
import com.daxia.ogmall.util.SpringSecurityUtils;
import com.daxia.ogmall.util.ValidationUtils;

@Service
public class CartService {
	private static Logger logger = Logger.getLogger(CartService.class);
	@Autowired
	private CartDAO cartDAO;
	@Autowired
	private SpecificationService specificationService;
	
	public List<CartDTO> find(CartDTO query, Page page) {
		List<Cart> models = cartDAO.find(query, page);
		List<CartDTO> dtos = toDTOs(models);
		return dtos;
	}
	
	public Integer getCartCountOfUser(Long userId) {
		return cartDAO.getCountByUser(userId);
	}
	
	public List<CartDTO> findAll() {
		return this.find(new CartDTO(), null);
	}
	
	public List<CartDTO> find(int count) {
		Page page = new Page();
		page.setPage(1);
		page.setPageSize(count);
		return this.find(new CartDTO(), page);
	}
	
	public Long create(CartDTO dto) {
		Cart model = new Cart();
		toModel(model, dto);
		return cartDAO.create(model);
	}
	
	public CartDTO load(Long id) {
	    Cart model = cartDAO.load(id);
	    return toDTO(model);
    }

	public void updateAllFields(CartDTO dto) {
		Cart model = cartDAO.load(dto.getId());
		toModel(model, dto);
		cartDAO.update(model);
    }

	public void deleteByIds(Long[] ids) {
		if (ids != null) {
			for (Long id : ids) {
				cartDAO.deleteById(id);
			}
		}
    }
	
	@Transactional
	public void createCarts(List<CartDTO> carts) {   //创建多个购物车信息
		for(CartDTO aDto:carts) {
			Cart model = new Cart();
			toModel(model, aDto);
			cartDAO.create(model);
		}
	}
	
	@Transactional
	public int updateCountAndStatusOfCarts(List<CartDTO> carts) {   //更新购物车中的状态和数量信息，以完成结算
		if(carts != null && carts.size() > 0) {
			int returnCount = 0;
			for(CartDTO cart:carts) {
				returnCount += cartDAO.updateStatusAndCount(cart);
			}
			return returnCount;
		} else {
			return 0;
		}
	}
	
	
	public void deleteById(Long id) {
		this.deleteByIds(new Long[] {id});
	}

	public CartDTO findOne(CartDTO query) {
		Cart model = cartDAO.findOne(query);
		return toDTO(model);
	}
	
	private List<CartDTO> toDTOs(List<Cart> models) {
		if (CollectionUtils.isEmpty(models)) {
			return new ArrayList<CartDTO>(0);
		}
		List<CartDTO> dtos = new ArrayList<CartDTO>(models.size());
		for (Cart model : models) {
	        CartDTO dto = toDTO(model);
	        dtos.add(dto);
        }
	    return dtos;
    }
    
    private CartDTO toDTO(Cart model) {
		if (model == null) {
			return null;
		}
		CartDTO dto = BeanMapper.map(model, CartDTO.class);
		
		return dto;
	}
	
	private void toModel(Cart model, CartDTO dto) {
		BeanMapper.copy(dto, model);
    }
	
	@SuppressWarnings("unused")
	private List<Cart> toModels(List<CartDTO> dtos) {
		if (CollectionUtils.isEmpty(dtos)) {
			return new ArrayList<Cart>(0);
		}
		List<Cart> models = new ArrayList<Cart>(dtos.size());
		for (CartDTO dto : dtos) {
	        Cart model = new Cart();
	        toModel(model, dto);
	        models.add(model);
        }
		return models;
	}

	@Transactional
	public void addToCart(Long productId, Integer quantity, Long specificationId) {
		ValidationUtils.assertTrue(productId != null && productId >= 0, "商品编码不能为空!");
    	ValidationUtils.assertTrue(specificationId != null && specificationId >= 0, "商品规格不能为空!");
    	if(quantity == null) {   //如果数量没有传入，默认为1
    		quantity = 1;
    	}
    	
    	SpecificationDTO s = specificationService.load(specificationId);
    	if (s.getProduct().getSellingStatus() == null || s.getProduct().getSellingStatus() != ProductSellingStatus.OnSell.getValue()) {
			throw new RuntimeException("产品已下架【" + s.getOgCode() + "】，不能加入购物车");
		}
    	CoreUser currentUser = SpringSecurityUtils.getCurrentUser();
    	ValidationUtils.assertTrue(currentUser != null, "您还没有登陆，请登录后使用购物车功能!");
    	CartDTO cartInfo = new CartDTO();
    	UserDTO user = new UserDTO();
    	user.setId(currentUser.getId());
    	ProductDTO product = new ProductDTO();
    	product.setId(productId); 
    	SpecificationDTO specification = new SpecificationDTO();
    	specification.setId(specificationId);
    	cartInfo.setSpecification(specification);
    	cartInfo.setUser(user);
    	cartInfo.setProduct(product);
    	cartInfo.setQuantity(quantity);
    	cartInfo.setStatus(CartStatus.New.getValue());
    	this.create(cartInfo);
	}
}
